﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;

using PrimeAlgos;
using SortAlgos;
using SearchAlgos;
using System.Collections;

namespace AlgoFun
{
    //Seraching  & Sorting http://www.codeproject.com/Articles/177363/Searching-and-Sorting-Algorithms-via-C
    
    public class AlgoStrap
    {
        public static void Main(string[] args)
        {
            AlgoStrap algoStrap = new AlgoStrap();            
            long[] inArray = Sorter.GetRandomLongArray(10, 100);

            #region List to Dic

            List<Moon> lstMoons = new List<Moon>()
            {
                new Moon() {Name="Ganymede"},
                new Moon() {Name="Ganymede"},
                new Moon() {Name="Europa"},
                new Moon() {Name="Ariel"},
            };

            List<Moon> dstListMoons = lstMoons.Distinct<Moon>(new MoonComperator()).ToList();
            Dictionary<string, Moon> dicMoons = lstMoons.Distinct(new MoonComperator()).ToDictionary(p => p.Name);

            #endregion


            #region Searching

            int[] searchIntArray = Sorter.GetRandomIntArray(1000, 100);

            Array.Sort(searchIntArray);

            int searchResLinear = Searcher.LinearSearch(ref searchIntArray, 44);

            int searchResBinary = Searcher.BinSearch(ref searchIntArray, 44);


            #endregion


			#region Sorting

			//http://en.wikipedia.org/wiki/Sorting_algorithm

			Sorter sorter = new Sorter();           			

			Console.WriteLine("inArray:" + string.Join(",", inArray));
			long[] results = sorter.BubbleSort(inArray);
			Console.WriteLine("bubble results:" + string.Join(",", inArray));

			results = sorter.QuickSort(inArray);
			Console.WriteLine("quick sort results:" + string.Join(",", inArray));

			Environment.Exit(0);

			#endregion


            #region Design By Contract - http://research.microsoft.com/en-us/projects/contracts/            

            int val = Divide(4, 0);

            #endregion


            #region ByRef vs ByValue - http://www.albahari.com/valuevsreftypes.aspx

            Point myPoint = new Point(0, 0);      // a new value-type variable
            Form myForm = new Form();             // a new reference-type variable
            TestPassByValue(myPoint, myForm);     // TestPassByValue is a method defined below


            Point myPointByRef = new Point(0, 0);             // a new value-type variable
            Form myFormByRef = new Form();                    // a new reference-type variable
            TestPassByRef(ref myPointByRef, ref myFormByRef); // TestPassByValue is a method defined below

            #endregion


            #region Running

            //PowerSet
            algoStrap.GetPowerSet();

            //Primes
            algoStrap.GetPrimes();

            //PowerSet (Linq)
            var colors = new List<KnownColor> { KnownColor.Red, KnownColor.Green, KnownColor.Blue, KnownColor.Yellow };
            var result = new PowerSet().GetPowerSet(colors);

            #endregion


            #region Not running

            /*             
             * algoStrap.GetPowerSet();
             * algoStrap.GetPrimes();              
             */

            #endregion


        }


        static int Divide(int numerator, int denominator)
        { 
            Contract.Requires<Exception>(denominator != 0);

            return numerator / denominator;
        }


        static void TestPassByValue(Point p, Form f)
        {
            p.X = 100;                      // No effect on MyPoint since p is a copy
            f.Text = "Hello, World!";       // This will change myForm’s caption since
                                            // myForm and f point to the same object
            f = null;                       // No effect on myForm
        }


        static void TestPassByRef(ref Point p, ref Form f)
        {
            p.X = 100;                      // No effect on MyPoint since p is a copy
            f.Text = "Hello, World!";       // This will change myForm’s caption since
                                            // myForm and f point to the same object
            f = null;                       // No effect on myForm
        }


        private void GetPrimes()
        {
            Primer primer = new Primer(30);
            int[] primes = primer.GetPrimesBruteForce();

            SievePrimer sievePrimer = new SievePrimer(30);
            SieveNumber[] primes2 = sievePrimer.GetPrimesUsingSieveOfEratosthenes();
        }


        private void GetPowerSet()
        {
            PowerSet ps = new PowerSet();
            var psResult = ps.GetPowerSet(new List<char> { 'A', 'B', 'C' });
        }

    }


    public enum KnownColor
    {
        Red,
        Green,
        Blue,
        Yellow
    }


    class Moon
    {
        public string Name { get; set; }
        public string Desc { get; set; }
    }


    class MoonComperator : IEqualityComparer<Moon>
    {
        public bool Equals(Moon x, Moon y)
        {
            return x.Name == y.Name;
        }

        public int GetHashCode(Moon obj)
        {
            return obj.Name.GetHashCode();
        }
    }
}
